from django.contrib.auth import authenticate
from ninja.errors import AuthenticationError
from ninja.security import HttpBasicAuth


class ModelAuth(HttpBasicAuth):
    """
    模仿 rest_framework.permissions.DjangoModelPermissions 实现

    使用时
        @router.get("/register", response=list[RegisterSchema], by_alias=True, auth=ModelAuth(Register)) # !!!!!! <-------- by_alias
        @paginate(PageNumberPagination)
        def get_register(request, page_size=50):
            return Register.objects.all()
    """
    def __init__(self,model) -> None:
        self.model = model
        super().__init__()

    perms_map = {
        'GET': ['%(app_label)s.view_%(model_name)s'],
        'OPTIONS': [],
        'HEAD': [],
        'POST': ['%(app_label)s.add_%(model_name)s'],
        'PUT': ['%(app_label)s.change_%(model_name)s'],
        'PATCH': ['%(app_label)s.change_%(model_name)s'],
        'DELETE': ['%(app_label)s.delete_%(model_name)s'],
    }

    def get_required_permissions(self, method, model_cls):
        """
        Given a model and an HTTP method, return the list of permission
        codes that the user is required to have.
        """
        kwargs = {
            'app_label': model_cls._meta.app_label,
            'model_name': model_cls._meta.model_name
        }

        if method not in self.perms_map:
            raise AuthenticationError("方法不允许")

        return [perm % kwargs for perm in self.perms_map[method]]

    def check_permission(self,request):
        perms = self.get_required_permissions(request.method, self.model)
        if not request.user.has_perms(perms):
            raise AuthenticationError("用户未权限")
    def authenticate(self, request, username, password):
        # 获取用户
        user = authenticate(request,username=username,password=password)
        if user:
            request.user = user
            self.check_permission(request)

            return user
